"""
Строки документации модуля должны, как правило, перечислять классы, исключения, функции 
(и любые другие объекты), которые экспортируются модулем, с краткими пояснениями 
(в одну строчку) каждого из них. (Эти строки, как правило, дают меньше деталей, 
чем первая строка документации к объекту). Строки документации пакета модулей 
(т.е. строка документации в __init__.py) также должны включать модули и подпакеты.
"""
# c:\Python34\Python.exe c:\all_codes\staff-future\code\python\access\access.py
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
import configparser


def OpenDB(config):
    """
Строки документации функции или метода должны обобщить его поведение и 
документировать свои аргументы, возвращаемые значения, побочные эффекты, 
исключения, дополнительные аргументы, именованные аргументы, и 
ограничения на вызов функции.
    """
    if QSqlDatabase.contains():                                         # если соединение уже имеется
        db = QSqlDatabase.database()                                    # используем его
    else:
        db = QSqlDatabase.addDatabase("QMYSQL")                         # создаём новое соединение
    server = config['SERVER']                                           # берём из конфиг секцию SERVER
    db.setHostName(server['HostName'])
    db.setDatabaseName(server['DatabaseName'])
    db.setUserName(server['UserName'])
    db.setPassword(server['Password'])
    if db.open():                                                       # открываем соединение
        print('открыли')
        return db
    else:
        error = db.lastError()
        num_error = error.number()
        if num_error == 1044:
            message = "Недопустимое имя базы данных. Проверьте правильность в поле [База]."
        elif num_error == 1045:
            message = "Недопустимое имя пользователи и/или пароль. Проверьте правильность в полях [Логин] и [Пароль]"
        elif num_error == 2003:
            message = "Сервер не отвечает на запросы. Проверьте правильность IP адреса в поле [Сервер]."
        else:
            message = ("код ошибки: {}. Оригинальное сообщение: {} "
                .format(num_error,error.text()))
        dialog = QMessageBox()
        dialog.setIcon(QMessageBox.Warning) # иконка
        dialog.setWindowTitle("СООБЩЕНИЯ СЕРВЕРА")
        dialog.setText(message)
        dialog.exec_()


class fmServer(QDialog):
    """
Строки документации класса обобщают его поведение и перечисляют открытые 
методы и переменные экземпляра. Если класс предназначен для подклассов, и 
имеет дополнительный интерфейс для подклассов, этот интерфейс должен быть 
указан отдельно (в строке документации). Конструктор класса должны быть 
задокументирован в документации метода __init__. Отдельные методы должны 
иметь свои строки документации.
"""

    def __init__(self, config):
        """
Создание диалогового окна типа форма.
        """
        super().__init__()                                              # запускаем init родительского класса
        self.config = config
        server = self.config['SERVER']                                  # берём из конфиг секцию SERVER
        self.edtHostName = QLineEdit(server['HostName'])                # текстовые поля формы
        self.edtDatabaseName = QLineEdit(server['DatabaseName'])
        self.edtUserName = QLineEdit(server['UserName'])
        self.edtPassword = QLineEdit(server['Password'])

        self.btnConnected = QPushButton('ПРОВЕРКА СОЕДИНЕНИЯ')          # кнопка
        self.btnConnected.clicked.connect(self.btnConnectedClick)

        self.form = QFormLayout()                                       # контейнер форма
        self.form.addRow("Сервер", self.edtHostName)
        self.form.addRow("База", self.edtDatabaseName)
        self.form.addRow("Логин", self.edtUserName)
        self.form.addRow("Пароль", self.edtPassword)
        self.form.addRow(self.btnConnected)
        self.setLayout(self.form)
        self.setWindowTitle("ПАРАМЕТРЫ СОЕДИНЕНИЯ")
        self.setMinimumWidth(300)


    def btnConnectedClick(self):
        """
Проверка заполнения полей. Загрузка значений полей в переменную конфигурации.
Попытка соединения с сервером. Закрытие формы в случае удачного соединения

        """
        if (not self.edtHostName.text() or                              # проверка заполнения полей
            not self.edtDatabaseName.text() or
            not self.edtUserName.text() or
            not self.edtPassword.text()):
            QMessageBox.information(window, "Текст заголовка",
                "Необходимо заполнить все поля.",
                buttons=QMessageBox.Close,
                defaultButton=QMessageBox.Close)
            return

        server = self.config['SERVER']                                  # берём из конфиг секцию SERVER
        server['HostName'] = self.edtHostName.text()                    # загрузка полей в
        server['DatabaseName'] = self.edtDatabaseName.text()
        server['UserName'] = self.edtUserName.text()
        server['Password'] = self.edtPassword.text()

        self.db = OpenDB(self.config)                                   # открываем соединение
        if self.db:                                                     #
            self.accept()

            
def ConnectServer():
    """
Читает конфиг файл. Если файл отсутствует, создает параметры соединения по-умолчанию.
Открывает соединение с параметрами из конфига. Если соединение не удалось открывает
модальную форму для настройки соединения с сервером. Если соединение удалось, 
записывает конфиг и возвращает указатель на базу данных.
    """
    path_file = os.getenv('APPDATA') + 'staff.ini'                      # путь до файла ini
    config = configparser.ConfigParser()                                # создаем переменную ini
    if not config.read(path_file):                                      # если конфиг пуст
        s = """
            [SERVER]
            HostName=localhost
            DatabaseName=staffnext
            UserName=staff
            Password=staff
            """
        config.read_string(s)
    db = OpenDB(config)                                                 # открываем соединение
    if not db:                                                          #
        dialog = fmServer(config)                                       # Создаем экземпляр формы
        result = dialog.exec_()                                         # запускаем модально
        if result == QDialog.Accepted:
            with open(path_file, 'w') as configfile:
                config.write(configfile)
            print("Удача")
            return dialog.db
    else:                                                               # ошибка открытия
        return db                                                       # соединение открыто


if __name__ == '__main__':
    app = QApplication(sys.argv)
    splash = QSplashScreen(QPixmap("splash.png"));
    splash.show();    
    db = ConnectServer()
    if db:
        pass
        # dialog = fmLogin()                                              # экземпляр формы Login
        # result = dialog.exec_()
        # if result == QDialog.Accepted:
            # windows = fmUsers()                                         # экземпляр формы Users
#    sys.exit(app.exec_())
    # db.close()
    # QSqlDatabase.removeDatabase()
